//! task 任务定义
#![no_std]

extern crate alloc;

use alloc::string::String;
use core::mem::offset_of;

/// task 任务定义
///
/// 对齐 C ABI, 汇编将进行访问
#[repr(C)]
pub struct Task {
    // 任务名字
    name: String,
    // 任务内核栈起始地址
    stack: usize,
    // 任务线程地址上限限制
    thread_addr_limit: usize,
    /// 线程 flags, 由架构管理
    pub thread_flags: u32,
    /// 线程抢占 count, 由架构管理
    pub thread_preempt: u32,
}

/// `TSK_STACK`
pub const TSK_STACK: usize = offset_of!(Task, stack);
/// `TSK_TI_ADDR_LIMIT`
pub const TSK_TI_ADDR_LIMIT: usize = offset_of!(Task, thread_addr_limit);
/// `TSK_TI_FLAGS`
pub const TSK_TI_FLAGS: usize = offset_of!(Task, thread_flags);
/// `TSK_TI_PREEMPT`
pub const TSK_TI_PREEMPT: usize = offset_of!(Task, thread_preempt);

impl Default for Task {
    fn default() -> Self {
        Self::new()
    }
}

impl Task {
    /// 构造 task
    pub const fn new() -> Self {
        Self {
            name: String::new(),
            stack: 0,
            thread_addr_limit: 0,
            thread_flags: 0,
            thread_preempt: 0,
        }
    }

    /// 任务名称
    #[inline(always)]
    pub fn name(&self) -> &str {
        &self.name
    }

    /// 任务栈基地址
    #[inline(always)]
    pub fn stack(&self) -> usize {
        self.stack
    }

    /// 线程地址限制
    #[inline(always)]
    pub fn thread_addr_limit(&self) -> usize {
        self.thread_addr_limit
    }
}

impl Task {
    /// 设置任务名称
    #[inline(always)]
    pub fn set_name(&mut self, name: &str) {
        self.name = String::from(name);
    }

    /// 设置任务栈基地址
    #[inline(always)]
    pub fn set_stack(&mut self, stack_base: usize) {
        self.stack = stack_base;
    }

    /// 设置线程地址限制
    #[inline(always)]
    pub fn set_thread_addr_limit(&mut self, limit: usize) {
        self.thread_addr_limit = limit;
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test() {
        assert_eq!(TSK_STACK, 24);
        assert_eq!(TSK_TI_ADDR_LIMIT, 32);
        assert_eq!(TSK_TI_FLAGS, 40);
        assert_eq!(TSK_TI_PREEMPT, 44);
    }
}
